﻿using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using Abp.UI;
using CPPProject.CPP.Dto;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace CPPProject.CPP
{
   public class CPPCategoryAppService : AsyncCrudAppService<CPPCategory, CPPCategoryDto, int, PagedResultRequestDto, CreateCPPCategoryDto, UpdateCPPCategoryDto>, ICPPCategoryAppService
    {
        private readonly IObjectMapper _objectMapper;
        public CPPCategoryAppService(
            IRepository<CPPCategory, int> repository,
            IObjectMapper objectMapper) : base(repository)
        {
            _objectMapper = objectMapper;
        }

        public async Task<PagedResultDto<CPPCategoryDto>> GetList(int skipCount = 0, int maxResultCount = 10, string layout = "")
        {
            PagedResultDto<CPPCategoryDto> resultDto = new PagedResultDto<CPPCategoryDto>();
            List<CPPCategory> lists = new List<CPPCategory>();
            Expression<Func<CPPCategory, bool>> expr = null;
            if (!string.IsNullOrEmpty(layout))
            {
                expr = expr == null ? o => o.Layout == layout && o.IsHide==false : expr.ExpressionAnd(o => o.Layout == layout && o.IsHide == false);
            }
            if (expr != null)
            {
                lists = await Repository.GetAllListAsync(expr);
                lists = lists.OrderBy(o => o.OrderId).ToList();
                var dtos = lists.Skip(skipCount).Take(maxResultCount).ToList();
                resultDto.Items = _objectMapper.Map<List<CPPCategoryDto>>(dtos);
                resultDto.TotalCount = lists.Count;
            }
            else
                resultDto = await base.GetAllAsync(new PagedResultRequestDto { MaxResultCount = maxResultCount, SkipCount = skipCount });
            return resultDto;
        }

        public async Task<List<CategoryTreeDto>> GetTreeListAsync(int parentId = 0)
        {
            var lists = await Repository.GetAllListAsync(o => o.IsDeleted == false);
            List<CategoryTreeDto> result = GetTree(lists, parentId);
            result = result.OrderBy(o => o.OrderId).ToList();
            return result;
        }

        private List<CategoryTreeDto> GetTree(List<CPPCategory> items, long parentid)
        {
            List<CategoryTreeDto> result = new List<CategoryTreeDto>();
            var lists = items.Where(o => o.ParentId == parentid).ToList();
            foreach (var item in lists)
            {
                CategoryTreeDto dobj = _objectMapper.Map<CategoryTreeDto>(item);
                var childs = items.Where(o => o.ParentId == item.Id).ToList();
                if (childs.Count > 0)
                {
                    dobj.Childs = childs.Count;
                    dobj.children = GetTree(items, item.Id);
                }
                result.Add(dobj);
            }
            return result;
        }
        public async Task<List<TreeDataDto>> GetTreeDataAsync(string layout, int parentId = 0)
        {
            var lists = await Repository.GetAllListAsync(o => o.Layout == layout && o.IsDeleted == false && o.IsHide==false);
            List<TreeDataDto> result = GetTreeData(lists, parentId);
            return result;
        }
        private List<TreeDataDto> GetTreeData(List<CPPCategory> items, long parentid)
        {
            List<TreeDataDto> result = new List<TreeDataDto>();
            var lists = items.Where(o => o.ParentId == parentid).ToList();
            foreach (var item in lists)
            {
                TreeDataDto dobj = new TreeDataDto();
                dobj.value = item.Id;
                dobj.title = item.CategoryName;
                dobj.node = item;
                var childs = items.Where(o => o.ParentId == item.Id).ToList();
                if (childs.Count > 0)
                {
                    dobj.children = GetTreeData(items, item.Id);
                }
                result.Add(dobj);
            }
            return result;
        }

        public async Task BatchDelete(long[] ids)
        {
            await Repository.DeleteAsync(o => ids.Contains(o.Id));
        }

        public async Task<CPPCategoryDto> GetCateByIdx(string cateIndex)
        {
            var lists = await Repository.GetAllListAsync(o => o.CategoryIndex == cateIndex);
            if (lists.Count > 0)
            {
                var obj = lists.FirstOrDefault();
                return _objectMapper.Map<CPPCategoryDto>(obj);
            }
            else
            {
                throw new UserFriendlyException("索引" + cateIndex + "不存在");
            }
        }

        public override async Task<CPPCategoryDto> CreateAsync(CreateCPPCategoryDto input)
        {
            var lists = await Repository.GetAllListAsync(o => o.CategoryName == input.CategoryName || o.CategoryIndex == input.CategoryIndex);
            if (lists.Count <= 0)
            {
                return await base.CreateAsync(input);
            }
            else
            {
                throw new UserFriendlyException(input.CategoryIndex + "已经存在");
            }
        }
        public override async Task<CPPCategoryDto> UpdateAsync(UpdateCPPCategoryDto input)
        {
            var lists = await Repository.GetAllListAsync(o => o.CategoryIndex == input.CategoryIndex && o.Id != input.Id);
            if (lists.Count <= 0)
            {
                return await base.UpdateAsync(input);
            }
            else
            {
                throw new UserFriendlyException(input.CategoryIndex + "已经存在");
            }
        }

        /// <summary>
        /// 是否推荐
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        [Microsoft.AspNetCore.Mvc.HttpPost]
        public async Task BatchRec(int[] ids)
        {
            foreach (int id in ids)
            {
                var obj = await Repository.GetAsync(id);
                obj.IsRec = !obj.IsRec;
            }
        }

        /// <summary>
        /// 资产类型下拉
        /// </summary>
        /// <returns></returns>
        public async Task<List<GetDoawRowDto>> GetDoawRow(string layout)
        {
            List<CPPCategory> lists = new List<CPPCategory>();
            List<GetDoawRowDto> list = new List<GetDoawRowDto>();
            lists = await Repository.GetAll().Where(o=>o.Layout==layout).ToListAsync();
            for (int i = 2; i < lists.Count; i++)
            {
                GetDoawRowDto getDoawRow = new GetDoawRowDto();
                getDoawRow.value = lists[i].Id.ToString();
                getDoawRow.label = lists[i].CategoryName;
                list.Add(getDoawRow);
            }
            return list;
        }

    }
}
